package com.lhj.xxsc.cart.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.xxsc.common.utils.R;
import com.lhj.xxsc.cart.feign.ProductFeignService;
import com.lhj.xxsc.cart.interceptor.CartInterceptor;
import com.lhj.xxsc.cart.service.CartService;
import com.lhj.xxsc.cart.to.SkuInfoEntityTo;
import com.lhj.xxsc.cart.to.UserInfoTo;
import com.lhj.xxsc.cart.vo.CartItemVo;
import com.lhj.xxsc.cart.vo.CartVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

/**
 * @author 罗惠江
 * @version 1.0
 * @email 1511619294@qq.com
 * @date 2020/12/30 14:01
 */
@Slf4j
@Service
public class CartServiceImpl implements CartService {

	/**
	 * redis 存储的 购物车
	 */
	private final static String CART_PREFIX = "xxsc:cart:";


	@Autowired
	StringRedisTemplate redisTemplate;

	@Autowired
	ProductFeignService productFeignService;

	@Autowired
	ThreadPoolExecutor executor;

	/**
	 * 添加商品到购物车
	 *
	 * @param skuId
	 * @param num
	 * @return
	 */
	@Override
	public CartItemVo addToCart(Long skuId, Integer num) throws ExecutionException, InterruptedException {

		// 获取购物车
		BoundHashOperations<String, Object, Object> cartOps = getCartOps();

		String res = (String) cartOps.get(skuId.toString());
		if (StringUtils.isEmpty(res)) {
			// 旧购物车无此商品
			// 添加新商品到购物车
			CartItemVo cartItemVo = new CartItemVo();
			CompletableFuture<Void> getSkuInfo = CompletableFuture.runAsync(() -> {

				// 调用远程接口查询商品信息
				R r = productFeignService.productInfo(skuId);
				if (r.getCode() == 0) {
					SkuInfoEntityTo skuInfo = r.getData("skuInfo", new TypeReference<SkuInfoEntityTo>() {
					});
					cartItemVo.setCheck(true);
					cartItemVo.setCount(num);
					cartItemVo.setImage(skuInfo.getSkuDefaultImg());
					cartItemVo.setTitle(skuInfo.getSkuTitle());
					cartItemVo.setSkuId(skuInfo.getSkuId());
					cartItemVo.setPrice(skuInfo.getPrice());

				}
			}, executor);

			CompletableFuture<Void> getSaleAttr = CompletableFuture.runAsync(() -> {
				List<String> skuSaleAttrValues = productFeignService.getSkuSaleAttrValues(skuId);
				// 远程调用 sku的 组合信息
				cartItemVo.setSkuAttr(skuSaleAttrValues);
			}, executor);
			CompletableFuture.allOf(getSkuInfo, getSaleAttr).get();
			cartOps.put(skuId.toString(), JSON.toJSONString(cartItemVo));
			return cartItemVo;
		} else {
			// 有商品，则只是修改数量
			CartItemVo cartItemVo = JSON.parseObject(res, CartItemVo.class);
			cartItemVo.setCount(cartItemVo.getCount() + num);
			cartOps.put(skuId.toString(), JSON.toJSONString(cartItemVo));
			return cartItemVo;
		}


	}

	/**
	 * 查询购物车中的某个购物项
	 *
	 * @param skuId
	 * @return
	 */
	@Override
	public CartItemVo getCartItem(Long skuId) {
		String str = (String) getCartOps().get(skuId.toString());
		CartItemVo cartItemVo = JSON.parseObject(str, CartItemVo.class);
		return cartItemVo;
	}

	@Override
	public CartVo getCart() throws ExecutionException, InterruptedException {
		CartVo cartVo = new CartVo();
		UserInfoTo userInfoTo = CartInterceptor.threadLocal.get();
		if (userInfoTo.getUserId() != null) {
			String cartKey = CART_PREFIX + userInfoTo.getUserId();
			String tempKey = CART_PREFIX + userInfoTo.getUserKey();
			List<CartItemVo> tempCartItems = getCartItems(tempKey);
			// 合并并且清空 临时购物车
			if (!CollectionUtils.isEmpty(tempCartItems)) {
				// 需要合并商品
				for (CartItemVo item : tempCartItems) {
					addToCart(item.getSkuId(), item.getCount());
				}
				clearCart(tempKey);
			}
			// 获取登录后的购物车数据
			List<CartItemVo> cartItems = getCartItems(cartKey);
			cartVo.setItems(cartItems);

		} else {
			String cartKey = CART_PREFIX + userInfoTo.getUserKey();
			// 获取临时购物车的所有购物项目
			List<CartItemVo> cartItems = getCartItems(cartKey);
			cartVo.setItems(cartItems);
		}
		return cartVo;
	}


	/**
	 * 获取我们当前用户的购物车
	 *
	 * @return
	 */
	private BoundHashOperations<String, Object, Object> getCartOps() {
		// 判断登录状态
		String cartKey = "";
		UserInfoTo userInfoTo = CartInterceptor.threadLocal.get();
		if (userInfoTo.getUserId() != null) {
			cartKey = CART_PREFIX + userInfoTo.getUserId();
		} else {
			cartKey = CART_PREFIX + userInfoTo.getUserKey();
		}
		BoundHashOperations<String, Object, Object> stringObjectObjectBoundHashOperations = redisTemplate.boundHashOps(cartKey);
		return stringObjectObjectBoundHashOperations;
	}

	private List<CartItemVo> getCartItems(String cartKey) {
		BoundHashOperations<String, Object, Object> hashOps = redisTemplate.boundHashOps(cartKey);
		List<Object> values = hashOps.values();
		if (!CollectionUtils.isEmpty(values)) {
			List<CartItemVo> itemVos = values.stream().map(obj -> {
				String str = (String) obj;
				CartItemVo cartItemVo = JSON.parseObject(str, CartItemVo.class);
				return cartItemVo;
			}).collect(Collectors.toList());
			return itemVos;
		}
		return null;
	}

	@Override
	public void clearCart(String cartKey) {
		redisTemplate.delete(cartKey);
	}


	/**
	 * 购物车的选中状态
	 *
	 * @param skuId
	 * @param check
	 */
	@Override
	public void checkItem(Long skuId, Integer check) {
		BoundHashOperations<String, Object, Object> cartOps = getCartOps();
		CartItemVo cartItem = getCartItem(skuId);
		cartItem.setCheck(check == 1 ? true : false);
		String cartItemStr = JSON.toJSONString(cartItem);
		cartOps.put(skuId.toString(), cartItemStr);
	}

	/**
	 * 修改购物车中的商品数量
	 *
	 * @param skuId
	 * @param num
	 */
	@Override
	public void changeItemCount(Long skuId, Integer num) {
		CartItemVo cartItem = getCartItem(skuId);
		cartItem.setCount(num);
		BoundHashOperations<String, Object, Object> cartOps = getCartOps();
		cartOps.put(skuId.toString(), JSON.toJSONString(cartItem));
	}

	@Override
	public void deleteItem(Long skuId) {
		BoundHashOperations<String, Object, Object> cartOps = getCartOps();
		cartOps.delete(skuId.toString());
	}

	@Override
	public List<CartItemVo> getUserCartItems() {
		List<CartItemVo> cartItemList = new ArrayList<>();
		UserInfoTo userInfoTo = CartInterceptor.threadLocal.get();
		if (userInfoTo.getUserId() != null) {
			List<CartItemVo> cartItems = getCartItems(CART_PREFIX + userInfoTo.getUserId());
			if (cartItems != null) {
				// 获取所有被选中的购物项
				cartItemList = cartItems.stream().filter(item -> item.getCheck()).collect(Collectors.toList());
				// 得到商品的id集合
				List<Long> skuIds = cartItemList.stream().map(item -> item.getSkuId()).collect(Collectors.toList());
				// 远程调用商品服务，获得商品当前价格
				R productPrices = productFeignService.getProductPrices(skuIds);

				if (productPrices.getCode() == 0) {
					Map<Long, BigDecimal> prices = productPrices.getData(new TypeReference<Map<Long, BigDecimal>>() {
					});
					cartItemList = cartItemList.stream().map(item -> {
						item.setPrice(prices.get(item.getSkuId()));
						return item;
					}).collect(Collectors.toList());
				} else {
					System.out.println("出现异常");
					//  throw ();
				}
				return cartItemList;
			}
		}
		return null;
	}
}
